﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace reformatter
{
    public class Reformat
    {
        private static readonly char[] Whitespaces = new char[] {' ', '\t', '\n', '\v', '\f', '\r'};
        // ' ' (0x20) space (SPC) 
        //'\t' (0x09) horizontal tab (TAB) 
        //'\n' (0x0a) newline (LF) 
        //'\v' (0x0b) vertical tab (VT) 
        //'\f' (0x0c) feed (FF) 
        //'\r' (0x0d) carriage return (CR) 


        public string Lese_Datei_ein(string eingabedatei)
        {
            var s = new StreamReader(eingabedatei);
            var inhalt = string.Empty;
            inhalt = s.ReadToEnd();
            return inhalt;
        }

        public int schreibe_zeilenweise(IEnumerable<string> zeilen, string ausgabedatei)
        {
            int fehlercode = 0;
            try
            {
                System.IO.StreamWriter w = new StreamWriter(ausgabedatei);
                foreach (string s in zeilen)
                {
                    w.WriteLine(s);
                }
                w.Close();
            }
            catch (Exception)
            {
                fehlercode = 1;
            }
            return fehlercode;
        }

        public IEnumerable<string> Aufteilen_in_Worte_an_Whitespaces(string eingabe)
        {
            string [] ret = eingabe.Split(Whitespaces);
            return ret;
        }

        public IEnumerable<string> Zeilen_bauen(IEnumerable<string> eingabe, int zeilenlänge)
        {
            IList<string> ret = new List<string>();
            var aktuelle_Zeile =new System.Text.StringBuilder(zeilenlänge);
            foreach (var wort in eingabe)
            {
                // Wenn aktuelles Wort hinzugefügt wird und dann die Länge überschriten würde,
                // Zeile hinzufügen und neue Zeile anlegen
                // Wenn die Zeile schon länger als erlaubt ist passt dieser Fall auch!
                if (aktuelle_Zeile.Length > 0 && aktuelle_Zeile.Length + wort.Length > zeilenlänge)
                {
                    if (aktuelle_Zeile.Length>0)
                    {
                        aktuelle_Zeile.Append(" ");
                    }
                    ret.Add(aktuelle_Zeile.ToString());
                    aktuelle_Zeile = new StringBuilder(zeilenlänge);
                }
                else
                {
                    aktuelle_Zeile.Append(wort);
                }
            }
            return ret;
        }

        public IEnumerable<string> formatieren(string  dateiinhalt, int zeilenlänge)
        {
            IEnumerable<string> worte = Aufteilen_in_Worte_an_Whitespaces(dateiinhalt);
            var zeilen = Zeilen_bauen(worte, zeilenlänge);
            return zeilen;
        }

        public Tuple<string, string, int> Lese_Eingabeparameter(string[] eingabe)
        {
            var eingabedatei = eingabe[0];
            var ausgabedatei = eingabe[1];
            int zeilenlänge ;
            int.TryParse(eingabe[2],out zeilenlänge);
            var ret = new Tuple<string, string, int>(eingabedatei, ausgabedatei, zeilenlänge);
            return ret;
        }

        public int format(string[] eingabe)
        {
            var parameter = Lese_Eingabeparameter(eingabe);
            var dateiinhalt = Lese_Datei_ein(parameter.Item1);
            var zeilen = formatieren(dateiinhalt, parameter.Item3);
            int fehlercode = schreibe_zeilenweise(zeilen,parameter.Item2);
            return fehlercode;
        }
    }
}